home *** CD-ROM | disk | FTP | other *** search
Wrap
/* File: USBKeypadKeyIn.c Contains: xxx put contents here xxx Version: xxx put version here xxx Copyright: © 1999 by Apple Computer, Inc., all rights reserved. Change History: Jan 00 gcummings Add Time Manager task to support Force Quit key sequence Add MyPostEvent glue code to accomodate the ForceQuit key patch which is expecting a long EventKind parameter instead of a word size parameter. */ /* USB Keyboard Translation to Macintosh */ #include <Types.h> #include <Events.h> #include <Resources.h> #include <LowMem.h> #include <USB.h> #include <Timer.h> #include "USBKeypad.h" extern usbKeyPadPBStruct myParamBlock; extern usbKeyPadPBStruct shimParamBlock; #define DOWN 0 #define UP 1 #define TRUE 1 #define FALSE 0 #define FakeADBAddr 16 #define FakeKBDType 2 // this should be the same as the Apple extended keyboard for now #define kRawEscapeKey 0x35 typedef struct { TMTask theTask; EventKind eventNum; UInt32 eventMsg; } TMTaskData; static UInt32 myKeyMAP[4]; static UInt32 keyTransState; static Handle handleKCHR; static UInt8* KCHRptr; static TMTaskData gTMTaskData; typedef KeyMap * KeyMapPtr; /* prototypes */ Boolean KeyInArray(UInt8 key, UInt8 *array, UInt16 len); Boolean SetBit(UInt8 *bitmapArray, UInt16 index, Boolean value); void PostADBKeyToMac(UInt16 virtualKeycode, UInt8 state); pascal OSErr MyPostEvent(EventKind eventNum, UInt32 eventMsg); void TimerCompletion(TMTaskData* taskData); /* when we move to master interfaces we can get this stuff from LowMemPriv.h */ /* be sure to turn on DIRECT_LOWMEM_ACCESSORS */ #define LMSetKbdVars(value) ((*(short *)0x0216) = (value)) #define LMSetKeyLast(value) ((*(short *)0x0184) = (value)) #define LMSetKeyTime(value) ((*(long *)0x0186) = (value)) #define LMSetKeyRepTime(value) ((*(long *)0x018A) = (value)) #define LMSetKeyMap(KeyMapValue) BlockMove((Ptr)(KeyMapValue), (Ptr)0x0174, sizeof(KeyMap)) // index represents USB keyboard usage value, content is Mac virtual keycode static UInt8 USBKMAPNumLockDown[256] = { 0xFF, /* 00 no event */ 0xFF, /* 01 ErrorRollOver */ 0xFF, /* 02 POSTFail */ 0xFF, /* 03 ErrorUndefined */ 0x00, /* 04 A */ 0x0B, /* 05 B */ 0x08, /* 06 C */ 0x02, /* 07 D */ 0x0E, /* 08 E */ 0x03, /* 09 F */ 0x05, /* 0A G */ 0x04, /* 0B H */ 0x22, /* 0C I */ 0x26, /* 0D J */ 0x28, /* 0E K */ 0x25, /* 0F L */ 0x2E, /* 10 M */ 0x2D, /* 11 N */ 0x1F, /* 12 O */ 0x23, /* 13 P */ 0x0C, /* 14 Q */ 0x0F, /* 15 R */ 0x01, /* 16 S */ 0x11, /* 17 T */ 0x20, /* 18 U */ 0x09, /* 19 V */ 0x0D, /* 1A W */ 0x07, /* 1B X */ 0x10, /* 1C Y */ 0x06, /* 1D Z */ 0x12, /* 1E 1/! */ 0x13, /* 1F 2/@ */ 0x14, /* 20 3 # */ 0x15, /* 21 4 $ */ 0x17, /* 22 5 % */ 0x16, /* 23 6 ^ */ 0x1A, /* 24 7 & */ 0x1C, /* 25 8 * */ 0x19, /* 26 9 ( */ 0x1D, /* 27 0 ) */ 0x24, /* 28 Return (Enter) */ 0x35, /* 29 ESC */ 0x33, /* 2A Delete (Backspace) */ 0x30, /* 2B Tab */ 0x31, /* 2C Spacebar */ 0x1B, /* 2D - _ */ 0x18, /* 2E = + */ 0x21, /* 2F [ { */ 0x1E, /* 30 ] } */ 0x2A, /* 31 \ | */ 0xFF, /* 32 Non-US # and ~ (what?!!!) */ 0x29, /* 33 ; : */ 0x27, /* 34 ' " */ 0x32, /* 35 ` ~ */ 0x2B, /* 36 , < */ 0x2F, /* 37 . > */ 0x2C, /* 38 / ? */ 0x39, /* 39 Caps Lock */ 0x7A, /* 3A F1 */ 0x78, /* 3B F2 */ 0x63, /* 3C F3 */ 0x76, /* 3D F4 */ 0x60, /* 3E F5 */ 0x61, /* 3F F6 */ 0x62, /* 40 F7 */ 0x64, /* 41 F8 */ 0x65, /* 42 F9 */ 0x6D, /* 43 F10 */ 0x67, /* 44 F11 */ 0x6F, /* 45 F12 */ 0x69, /* 46 F13/PrintScreen */ 0x6B, /* 47 F14/ScrollLock */ 0x71, /* 48 F15/Pause */ 0x72, /* 49 Insert */ 0x73, /* 4A Home */ 0x74, /* 4B PageUp */ 0x75, /* 4C Delete Forward */ 0x77, /* 4D End */ 0x79, /* 4E PageDown */ 0x7C, /* 4F RightArrow */ 0x7B, /* 50 LeftArrow */ 0x7D, /* 51 DownArrow */ 0x7E, /* 52 UpArrow */ 0x47, /* 53 NumLock/Clear */ 0x4B, /* 54 Keypad / */ 0x43, /* 55 Keypad * */ 0x4E, /* 56 Keypad - */ 0x45, /* 57 Keypad + */ 0x4C, /* 58 Keypad Enter */ 0x53, /* 59 Keypad 1 */ 0x54, /* 5A Keypad 2 */ 0x55, /* 5B Keypad 3 */ 0x56, /* 5C Keypad 4 */ 0x57, /* 5D Keypad 5 */ 0x58, /* 5E Keypad 6 */ 0x59, /* 5F Keypad 7 */ 0x5B, /* 60 Keypad 8 */ 0x5C, /* 61 Keypad 9 */ 0x52, /* 62 Keypad 0 */ 0x41, /* 63 Keypad . */ 0xFF, /* 64 Non-US \ and | (what ??!!) */ 0x6E, /* 65 ApplicationKey (not on a mac!)*/ 0x7F, /* 66 PowerKey */ 0x51, /* 67 Keypad = */ 0x69, /* 68 F13 */ 0x6B, /* 69 F14 */ 0x71, /* 6A F15 */ 0xFF, /* 6B F16 */ 0xFF, /* 6C F17 */ 0xFF, /* 6D F18 */ 0xFF, /* 6E F19 */ 0xFF, /* 6F F20 */ 0x5B, /* 70 F21 */ 0x5C, /* 71 F22 */ 0x52, /* 72 F23 */ 0x41, /* 73 F24 */ 0xFF, /* 74 Execute */ 0xFF, /* 75 Help */ 0x7F, /* 76 Menu */ 0x4C, /* 77 Select */ 0x69, /* 78 Stop */ 0x6B, /* 79 Again */ 0x71, /* 7A Undo */ 0xFF, /* 7B Cut */ 0xFF, /* 7C Copy */ 0xFF, /* 7D Paste */ 0xFF, /* 7E Find */ 0xFF, /* 7F Mute */ 0xFF, /* 80 no event */ 0xFF, /* 81 no event */ 0xFF, /* 82 no event */ 0xFF, /* 83 no event */ 0xFF, /* 84 no event */ 0xFF, /* 85 no event */ 0xFF, /* 86 no event */ 0xFF, /* 87 no event */ 0xFF, /* 88 no event */ 0xFF, /* 89 no event */ 0xFF, /* 8A no event */ 0xFF, /* 8B no event */ 0xFF, /* 8C no event */ 0xFF, /* 8D no event */ 0xFF, /* 8E no event */ 0xFF, /* 8F no event */ 0xFF, /* 90 no event */ 0xFF, /* 91 no event */ 0xFF, /* 92 no event */ 0xFF, /* 93 no event */ 0xFF, /* 94 no event */ 0xFF, /* 95 no event */ 0xFF, /* 96 no event */ 0xFF, /* 97 no event */ 0xFF, /* 98 no event */ 0xFF, /* 99 no event */ 0xFF, /* 9A no event */ 0xFF, /* 9B no event */ 0xFF, /* 9C no event */ 0xFF, /* 9D no event */ 0xFF, /* 9E no event */ 0xFF, /* 9F no event */ 0xFF, /* A0 no event */ 0xFF, /* A1 no event */ 0xFF, /* A2 no event */ 0xFF, /* A3 no event */ 0xFF, /* A4 no event */ 0xFF, /* A5 no event */ 0xFF, /* A6 no event */ 0xFF, /* A7 no event */ 0xFF, /* A8 no event */ 0xFF, /* A9 no event */ 0xFF, /* AA no event */ 0xFF, /* AB no event */ 0xFF, /* AC no event */ 0xFF, /* AD no event */ 0xFF, /* AE no event */ 0xFF, /* AF no event */ 0xFF, /* B0 no event */ 0xFF, /* B1 no event */ 0xFF, /* B2 no event */ 0xFF, /* B3 no event */ 0xFF, /* B4 no event */ 0xFF, /* B5 no event */ 0xFF, /* B6 no event */ 0xFF, /* B7 no event */ 0xFF, /* B8 no event */ 0xFF, /* B9 no event */ 0xFF, /* BA no event */ 0xFF, /* BB no event */ 0xFF, /* BC no event */ 0xFF, /* BD no event */ 0xFF, /* BE no event */ 0xFF, /* BF no event */ 0xFF, /* C0 no event */ 0xFF, /* C1 no event */ 0xFF, /* C2 no event */ 0xFF, /* C3 no event */ 0xFF, /* C4 no event */ 0xFF, /* C5 no event */ 0xFF, /* C6 no event */ 0xFF, /* C7 no event */ 0xFF, /* C8 no event */ 0xFF, /* C9 no event */ 0xFF, /* CA no event */ 0xFF, /* CB no event */ 0xFF, /* CC no event */ 0xFF, /* CD no event */ 0xFF, /* CE no event */ 0xFF, /* CF no event */ 0xFF, /* D0 no event */ 0xFF, /* D1 no event */ 0xFF, /* D2 no event */ 0xFF, /* D3 no event */ 0xFF, /* D4 no event */ 0xFF, /* D5 no event */ 0xFF, /* D6 no event */ 0xFF, /* D7 no event */ 0xFF, /* D8 no event */ 0xFF, /* D9 no event */ 0xFF, /* DA no event */ 0xFF, /* DB no event */ 0xFF, /* DC no event */ 0xFF, /* DD no event */ 0xFF, /* DE no event */ 0xFF, /* DF no event */ 0x3B, /* E0 left control key */ 0x38, /* E1 left shift key key */ 0x3A, /* E2 left alt/option key */ 0x37, /* E3 left GUI (windows/cmd) key */ 0x3E, /* E4 right control key */ 0x3C, /* E5 right shift key key */ 0x3D, /* E6 right alt/option key */ 0x37, /* E7 right GUI (windows/cmd) key */ 0xFF, /* E8 no event */ 0xFF, /* E9 no event */ 0xFF, /* EA no event */ 0xFF, /* EB no event */ 0xFF, /* EC no event */ 0xFF, /* ED no event */ 0xFF, /* EE no event */ 0xFF, /* EF no event */ 0xFF, /* F0 no event */ 0xFF, /* F1 no event */ 0xFF, /* F2 no event */ 0xFF, /* F3 no event */ 0xFF, /* F4 no event */ 0xFF, /* F5 no event */ 0xFF, /* F6 no event */ 0xFF, /* F7 no event */ 0xFF, /* F8 no event */ 0xFF, /* F9 no event */ 0xFF, /* FA no event */ 0xFF, /* FB no event */ 0xFF, /* FC no event */ 0xFF, /* FD no event */ 0xFF, /* FE no event */ 0xFF, /* FF no event */ }; // index represents USB keyboard usage value, content is Mac virtual keycode static UInt8 USBKMAPNumLockUp[256] = { 0xFF, /* 00 no event */ 0xFF, /* 01 ErrorRollOver */ 0xFF, /* 02 POSTFail */ 0xFF, /* 03 ErrorUndefined */ 0x00, /* 04 A */ 0x0B, /* 05 B */ 0x08, /* 06 C */ 0x02, /* 07 D */ 0x0E, /* 08 E */ 0x03, /* 09 F */ 0x05, /* 0A G */ 0x04, /* 0B H */ 0x22, /* 0C I */ 0x26, /* 0D J */ 0x28, /* 0E K */ 0x25, /* 0F L */ 0x2E, /* 10 M */ 0x2D, /* 11 N */ 0x1F, /* 12 O */ 0x23, /* 13 P */ 0x0C, /* 14 Q */ 0x0F, /* 15 R */ 0x01, /* 16 S */ 0x11, /* 17 T */ 0x20, /* 18 U */ 0x09, /* 19 V */ 0x0D, /* 1A W */ 0x07, /* 1B X */ 0x10, /* 1C Y */ 0x06, /* 1D Z */ 0x12, /* 1E 1/! */ 0x13, /* 1F 2/@ */ 0x14, /* 20 3 # */ 0x15, /* 21 4 $ */ 0x17, /* 22 5 % */ 0x16, /* 23 6 ^ */ 0x1A, /* 24 7 & */ 0x1C, /* 25 8 * */ 0x19, /* 26 9 ( */ 0x1D, /* 27 0 ) */ 0x24, /* 28 Return (Enter) */ 0x35, /* 29 ESC */ 0x33, /* 2A Delete (Backspace) */ 0x30, /* 2B Tab */ 0x31, /* 2C Spacebar */ 0x1B, /* 2D - _ */ 0x18, /* 2E = + */ 0x21, /* 2F [ { */ 0x1E, /* 30 ] } */ 0x2A, /* 31 \ | */ 0xFF, /* 32 Non-US # and ~ (what?!!!) */ 0x29, /* 33 ; : */ 0x27, /* 34 ' " */ 0x32, /* 35 ` ~ */ 0x2B, /* 36 , < */ 0x2F, /* 37 . > */ 0x2C, /* 38 / ? */ 0x39, /* 39 Caps Lock */ 0x7A, /* 3A F1 */ 0x78, /* 3B F2 */ 0x63, /* 3C F3 */ 0x76, /* 3D F4 */ 0x60, /* 3E F5 */ 0x61, /* 3F F6 */ 0x62, /* 40 F7 */ 0x64, /* 41 F8 */ 0x65, /* 42 F9 */ 0x6D, /* 43 F10 */ 0x67, /* 44 F11 */ 0x6F, /* 45 F12 */ 0x69, /* 46 F13/PrintScreen */ 0x6B, /* 47 F14/ScrollLock */ 0x71, /* 48 F15/Pause */ 0x72, /* 49 Insert */ 0x73, /* 4A Home */ 0x74, /* 4B PageUp */ 0x75, /* 4C Delete Forward */ 0x77, /* 4D End */ 0x79, /* 4E PageDown */ 0x7C, /* 4F RightArrow */ 0x7B, /* 50 LeftArrow */ 0x7D, /* 51 DownArrow */ 0x7E, /* 52 UpArrow */ 0x47, /* 53 NumLock/Clear */ 0x4B, /* 54 Keypad / */ 0x43, /* 55 Keypad * */ 0x4E, /* 56 Keypad - */ 0x45, /* 57 Keypad + */ 0x4C, /* 58 Keypad Enter */ 0x77, /* 59 Keypad 1 = End on keyapd*/ 0x7D, /* 5A Keypad 2 = Down Arrow on keypad*/ 0x79, /* 5B Keypad 3 = Page Down on keypad*/ 0x7B, /* 5C Keypad 4 = Left Arrow on keypad*/ 0x57, /* 5D Keypad 5 */ 0x7C, /* 5E Keypad 6 = Right Arrow on keypad*/ 0x73, /* 5F Keypad 7 = HOME on keypad*/ 0x7E, /* 60 Keypad 8 = Up Arrow on keypad*/ 0x74, /* 61 Keypad 9 = Page Up on keypad*/ 0x72, /* 62 Keypad 0 = Insert on keypad*/ 0x75, /* 63 Keypad . = Delete (forward) on keypad*/ 0xFF, /* 64 Non-US \ and | (what ??!!) */ 0x6E, /* 65 ApplicationKey (not on a mac!)*/ 0x7F, /* 66 PowerKey */ 0x51, /* 67 Keypad = */ 0x69, /* 68 F13 */ 0x6B, /* 69 F14 */ 0x71, /* 6A F15 */ 0xFF, /* 6B F16 */ 0xFF, /* 6C F17 */ 0xFF, /* 6D F18 */ 0xFF, /* 6E F19 */ 0xFF, /* 6F F20 */ 0x5B, /* 70 F21 */ 0x5C, /* 71 F22 */ 0x52, /* 72 F23 */ 0x41, /* 73 F24 */ 0xFF, /* 74 Execute */ 0xFF, /* 75 Help */ 0x7F, /* 76 Menu */ 0x4C, /* 77 Select */ 0x69, /* 78 Stop */ 0x6B, /* 79 Again */ 0x71, /* 7A Undo */ 0xFF, /* 7B Cut */ 0xFF, /* 7C Copy */ 0xFF, /* 7D Paste */ 0xFF, /* 7E Find */ 0xFF, /* 7F Mute */ 0xFF, /* 80 no event */ 0xFF, /* 81 no event */ 0xFF, /* 82 no event */ 0xFF, /* 83 no event */ 0xFF, /* 84 no event */ 0xFF, /* 85 no event */ 0xFF, /* 86 no event */ 0xFF, /* 87 no event */ 0xFF, /* 88 no event */ 0xFF, /* 89 no event */ 0xFF, /* 8A no event */ 0xFF, /* 8B no event */ 0xFF, /* 8C no event */ 0xFF, /* 8D no event */ 0xFF, /* 8E no event */ 0xFF, /* 8F no event */ 0xFF, /* 90 no event */ 0xFF, /* 91 no event */ 0xFF, /* 92 no event */ 0xFF, /* 93 no event */ 0xFF, /* 94 no event */ 0xFF, /* 95 no event */ 0xFF, /* 96 no event */ 0xFF, /* 97 no event */ 0xFF, /* 98 no event */ 0xFF, /* 99 no event */ 0xFF, /* 9A no event */ 0xFF, /* 9B no event */ 0xFF, /* 9C no event */ 0xFF, /* 9D no event */ 0xFF, /* 9E no event */ 0xFF, /* 9F no event */ 0xFF, /* A0 no event */ 0xFF, /* A1 no event */ 0xFF, /* A2 no event */ 0xFF, /* A3 no event */ 0xFF, /* A4 no event */ 0xFF, /* A5 no event */ 0xFF, /* A6 no event */ 0xFF, /* A7 no event */ 0xFF, /* A8 no event */ 0xFF, /* A9 no event */ 0xFF, /* AA no event */ 0xFF, /* AB no event */ 0xFF, /* AC no event */ 0xFF, /* AD no event */ 0xFF, /* AE no event */ 0xFF, /* AF no event */ 0xFF, /* B0 no event */ 0xFF, /* B1 no event */ 0xFF, /* B2 no event */ 0xFF, /* B3 no event */ 0xFF, /* B4 no event */ 0xFF, /* B5 no event */ 0xFF, /* B6 no event */ 0xFF, /* B7 no event */ 0xFF, /* B8 no event */ 0xFF, /* B9 no event */ 0xFF, /* BA no event */ 0xFF, /* BB no event */ 0xFF, /* BC no event */ 0xFF, /* BD no event */ 0xFF, /* BE no event */ 0xFF, /* BF no event */ 0xFF, /* C0 no event */ 0xFF, /* C1 no event */ 0xFF, /* C2 no event */ 0xFF, /* C3 no event */ 0xFF, /* C4 no event */ 0xFF, /* C5 no event */ 0xFF, /* C6 no event */ 0xFF, /* C7 no event */ 0xFF, /* C8 no event */ 0xFF, /* C9 no event */ 0xFF, /* CA no event */ 0xFF, /* CB no event */ 0xFF, /* CC no event */ 0xFF, /* CD no event */ 0xFF, /* CE no event */ 0xFF, /* CF no event */ 0xFF, /* D0 no event */ 0xFF, /* D1 no event */ 0xFF, /* D2 no event */ 0xFF, /* D3 no event */ 0xFF, /* D4 no event */ 0xFF, /* D5 no event */ 0xFF, /* D6 no event */ 0xFF, /* D7 no event */ 0xFF, /* D8 no event */ 0xFF, /* D9 no event */ 0xFF, /* DA no event */ 0xFF, /* DB no event */ 0xFF, /* DC no event */ 0xFF, /* DD no event */ 0xFF, /* DE no event */ 0xFF, /* DF no event */ 0x3B, /* E0 left control key */ 0x38, /* E1 left shift key key */ 0x3A, /* E2 left alt/option key */ 0x37, /* E3 left GUI (windows/cmd) key */ 0x3E, /* E4 right control key */ 0x3C, /* E5 right shift key key */ 0x3D, /* E6 right alt/option key */ 0x37, /* E7 right GUI (windows/cmd) key */ 0xFF, /* E8 no event */ 0xFF, /* E9 no event */ 0xFF, /* EA no event */ 0xFF, /* EB no event */ 0xFF, /* EC no event */ 0xFF, /* ED no event */ 0xFF, /* EE no event */ 0xFF, /* EF no event */ 0xFF, /* F0 no event */ 0xFF, /* F1 no event */ 0xFF, /* F2 no event */ 0xFF, /* F3 no event */ 0xFF, /* F4 no event */ 0xFF, /* F5 no event */ 0xFF, /* F6 no event */ 0xFF, /* F7 no event */ 0xFF, /* F8 no event */ 0xFF, /* F9 no event */ 0xFF, /* FA no event */ 0xFF, /* FB no event */ 0xFF, /* FC no event */ 0xFF, /* FD no event */ 0xFF, /* FE no event */ 0xFF, /* FF no event */ }; static RoutineDescriptor gTimerCompletionUPP = BUILD_ROUTINE_DESCRIPTOR(uppTimerProcInfo, (ProcPtr)TimerCompletion); void InitUSBKeyboard() { handleKCHR = GetResource('KCHR',0); // US keyboard mapping (handled differently by ADB Mgr) HLock(handleKCHR); KCHRptr = (UInt8 *)*handleKCHR; } void PostUSBKeyToMac(UInt16 rawUSBkey) { static UInt8 oldLEDState = 0x00; static UInt8 newLEDState = 0x00; static UInt8 capsLockState = 0x00; static UInt8 numLockState = 0x00; static UInt8 scrollLockState = 0x00; register UInt8 virtualKeycode, keystate; if (KCHRptr == 0) { InitUSBKeyboard(); } keystate = (rawUSBkey & 0x8000) ? UP : DOWN; rawUSBkey &= 0x0FF; if (keystate == DOWN) { newLEDState = oldLEDState; switch (rawUSBkey) { // Note: This switch statement is being left it to make it easy to add "toggling" keys in the future. // it used to support toggled numlock & scroll lock... It doesn't anymore. case kUSBNumLockKey: newLEDState ^= (1 << kNumLockLED); keystate = (newLEDState & (1 << kNumLockLED)) ? DOWN : UP; break; } if (newLEDState != oldLEDState) { oldLEDState = newLEDState; //USBHIDControlDevice(kHIDSetLEDStateByBits, &newLEDState); } } if (rawUSBkey == kUSBNumLockKey) { return; } // look up rawUSBkey in KMAP resource to get virtual keycode if (rawUSBkey < sizeof(USBKMAPNumLockDown)) { if (oldLEDState & kNumLockLEDMask) { virtualKeycode = USBKMAPNumLockDown[rawUSBkey]; } else { virtualKeycode = USBKMAPNumLockUp[rawUSBkey]; } } else { // DebugStr("\pPostUSBKeyToMac: Need bigger KMAP table"); virtualKeycode = 0xFF; } PostADBKeyToMac(virtualKeycode, keystate); if (virtualKeycode == 0x7F) PostADBKeyToMac(virtualKeycode, keystate); } void PostADBKeyToMac(UInt16 virtualKeycode, UInt8 state) { UInt32 keyEventMsg; EventKind keyEventKind; if (virtualKeycode > 127) return; // not handled by MacOS! // stop repeating LMSetKeyLast(0); LMSetKbdVars(0); // update our keymap SetBit((UInt8 *)myKeyMAP, virtualKeycode, state == DOWN ? 1 : 0); LMSetKeyMap(&myKeyMAP); // set this keyboard as the last keyboard LMSetKbdLast(FakeADBAddr); LMSetKbdType(FakeKBDType); // call KeyTrans to get character code virtualKeycode |= ((myKeyMAP[1]<<9) & 0x00FE00) | ((myKeyMAP[1]>>7) & 0x0100) | ((state==UP) ? 0x080 : 0); keyEventMsg = KeyTranslate(KCHRptr, virtualKeycode , &keyTransState); virtualKeycode &= 0x7F; if (gTMTaskData.theTask.qType < 0) // task is active so kill it RmvTime((QElemPtr)&gTMTaskData.theTask); if (keyEventMsg & 0xFFFF0000) { // post event UInt32 event = (keyEventMsg & 0xFF000000) | ((FakeADBAddr << 16) & 0x0FF0000) | ((virtualKeycode << 8) & 0x0FF00) | ((keyEventMsg>>16) & 0x0FF); if (state == DOWN) { UInt32 ticks = TickCount(); LMSetKeyTime(ticks); LMSetKeyRepTime(ticks); LMSetKeyLast(event & 0x0FFFF); LMSetKbdVars((event>>16) & 0x0FFFF); } keyEventKind = (state == DOWN ? keyDown : keyUp); if (/*!inMacsbug && */ (virtualKeycode == kRawEscapeKey)) { gTMTaskData.eventNum = keyEventKind; gTMTaskData.eventMsg = event; gTMTaskData.theTask.tmAddr = &gTimerCompletionUPP; gTMTaskData.theTask.tmCount = 0; gTMTaskData.theTask.tmWakeUp = 0; gTMTaskData.theTask.tmReserved = 0; InsTime((QElemPtr)&gTMTaskData.theTask); // install our task PrimeTime((QElemPtr)&gTMTaskData.theTask, 10L); // run as soon as 68K interrupts are enabled } else { // post the keys directly MyPostEvent(keyEventKind, event); } } if (keyEventMsg & 0x0000FFFF) { // post event UInt32 event =((keyEventMsg<<16) & 0xFF000000) | ((FakeADBAddr << 16) & 0x0FF0000) | ((virtualKeycode << 8) & 0x0FF00) | (keyEventMsg & 0x0FF); if (state == DOWN){ UInt32 ticks = TickCount(); LMSetKeyTime(ticks); LMSetKeyRepTime(ticks); LMSetKeyLast(event & 0x0FFFF); LMSetKbdVars((event>>16) & 0x0FFFF); } keyEventKind = (state == DOWN ? keyDown : keyUp); if (/*!inMacsbug && */ (virtualKeycode == kRawEscapeKey)) { gTMTaskData.eventNum = keyEventKind; gTMTaskData.eventMsg = event; gTMTaskData.theTask.tmAddr = &gTimerCompletionUPP; gTMTaskData.theTask.tmCount = 0; gTMTaskData.theTask.tmWakeUp = 0; gTMTaskData.theTask.tmReserved = 0; InsTime((QElemPtr)&gTMTaskData.theTask); // install our task PrimeTime((QElemPtr)&gTMTaskData.theTask, 10L); // run as soon as 68K interrupts are enabled } else { // post the keys directly MyPostEvent(keyEventKind, event); } } } // Sets the bitmapArray[index] to value // returns old value; Boolean SetBit(UInt8 *bitmapArray, UInt16 index, Boolean value) { UInt32 mask = 0x1 << (index % 8 ); Boolean oldVal; oldVal = (bitmapArray[index/8] & mask) ? TRUE : FALSE; if (value){ bitmapArray[index/8] |= mask; }else{ bitmapArray[index/8] &= ~mask; } return (oldVal); } void USBDemoKeyIn(UInt32 refcon, void * theData) { #pragma unused (refcon) USBHIDDataPtr pTheKeyboardData; register UInt8 i; pTheKeyboardData = (USBHIDDataPtr)theData; for (i=0; i<pTheKeyboardData->kbd.keycount; i++) { // no shim installed, let's just post some Macintosh keyevents PostUSBKeyToMac(pTheKeyboardData->kbd.usbkeycode[i]); } } OSStatus USBHIDControlDevice(UInt32 theControlSelector, void * theControlData) { #pragma unused (theControlData) switch (theControlSelector) { case kHIDSetLEDStateByBits: break; case kHIDEnableDemoMode: USBExpertStatus(myParamBlock.deviceRef, "\pTenKey Driver: Demo Mode Enabled", myParamBlock.deviceRef); break; case kHIDDisableDemoMode: USBExpertStatus(myParamBlock.deviceRef, "\pTenKey Driver: Demo Mode Disabled", myParamBlock.deviceRef); break; default: return paramErr; } return 0; } void ProcessInterruptReport(UInt8 hidReport[]) { UInt8 i, j, newkey, oldkey, deltas; UInt8 changedmodifiers, keycount; USBHIDData theKeyboardData; Boolean keypressedflag, keyreleasedflag; deltas = 0; if (myParamBlock.hidEmulationInit == false) { myParamBlock.hidEmulationInit = true; for (i = 0; i < kKeyboardReportSize; i++) myParamBlock.oldHIDReport[i] = 0; }; myParamBlock.oldHIDReport[1] = 0x0; hidReport[1] = 0x0; for (i = 0; i < kKeyboardReportSize; i++) { if (hidReport[i] != myParamBlock.oldHIDReport[i]) { deltas++; } } if ((myParamBlock.sendRawReportFlag) && deltas) { USBDemoKeyIn(0xff, (void *)&hidReport[0]); } else { if (deltas) { keycount = 0; changedmodifiers = hidReport[0] ^ myParamBlock.oldHIDReport[0]; if (changedmodifiers) { for (i = 0; i < kKeyboardModifierBits; i++) { if (changedmodifiers & (1 << i)) { if (hidReport[0] & (1 << i)) { theKeyboardData.kbd.usbkeycode[keycount++] = (0xe0 + i); } else { theKeyboardData.kbd.usbkeycode[keycount++] = (0x80e0 + i); } } } myParamBlock.oldHIDReport[0] = hidReport[0]; } if ((hidReport[kKeyboardOffsetToKeys] == 0) || (hidReport[kKeyboardOffsetToKeys] > 0x03)) { // While this double loop may look strange, I refer you to appendix C, of the HID Devices specification. // pp. 73 & 74 clearly state that report order is abitrary and does not reflect the order of events. // to quote: "The order of keycodes in array fields has no significance. Order determination is done // by the host software comparing the contents of the previous report to the current report. If two or // more keys are pressed in one report, their order is indeterminate. Keyboards may buffer events that // would have otherwise resulted in multiple events in a single report". // Because this specification (or lack thereof) states that the order is indeterminant, we have to // check all the old keys against all the new keys... for (i = kKeyboardOffsetToKeys; i < (kKeyboardOffsetToKeys + kKeyboardReportKeys); i++) { keypressedflag = true; newkey = hidReport[i]; keyreleasedflag = true; oldkey = myParamBlock.oldHIDReport[i]; for (j = kKeyboardOffsetToKeys; j < (kKeyboardOffsetToKeys + kKeyboardReportKeys); j++) // then look through all the keys that were previously and are currently reported as pressed { if (newkey == myParamBlock.oldHIDReport[j]) // was this new key already pressed? { keypressedflag = false; // if it was, then don't report it as being pressed. } if (oldkey == hidReport[j]) // Is the old key still pressed? { keyreleasedflag = false; // If yes, then don't report it as being released } } if ((newkey > 0x03) && keypressedflag) { theKeyboardData.kbd.usbkeycode[keycount++] = newkey; } if ((oldkey > 0x03) && keyreleasedflag) { theKeyboardData.kbd.usbkeycode[keycount++] = (oldkey + 0x8000); } if (keycount > 20) // a worse case scenario is: { // 4 modifier keys up break; // the other 4 modifier keys down } // 6 previously reported keys up } // 6 newly reported keys down // 6 + 6 + 4 + 4 = 20 for (i = 0; i<kKeyboardReportSize; i++) { myParamBlock.oldHIDReport[i] = hidReport[i]; }; } if (keycount) { theKeyboardData.kbd.keycount = keycount; USBDemoKeyIn(myParamBlock.interruptRefcon, (void *)&theKeyboardData); } } } } // This version of PostEvent works around a problem in the force-quit detection where the EventKind // is being treated (incorrectly) as an UInt32 pascal OSErr MyPostEvent(EventKind eventNum, UInt32 eventMsg) { return (OSErr) CallUniversalProc( (UniversalProcPtr)GetOSTrapAddress(0xA02F), kRegisterBased | RESULT_SIZE(SIZE_CODE(sizeof(OSErr))) | REGISTER_ROUTINE_PARAMETER(1, kRegisterA0, SIZE_CODE(sizeof(UInt32))) | REGISTER_ROUTINE_PARAMETER(2, kRegisterD0, SIZE_CODE(sizeof(UInt32))), eventNum, eventMsg); // parameter(s) } void TimerCompletion(TMTaskData* taskData) { OSErr err; RmvTime((QElemPtr)&taskData->theTask); err = MyPostEvent(taskData->eventNum, taskData->eventMsg); }